import UIKit
import PluggableApplicationDelegate

@UIApplicationMain
class AppDelegate: PluggableApplicationDelegate {
    
    override var services: [ApplicationService] {
        var allService = [ApplicationService]()
        
        allService.appendList(createServiceFrom(bundle: Bundle.main))
        allService.appendList(createServiceFromStaticFrameworks())
        Bundle.allFrameworks.forEach { allService.appendList(createServiceFrom(bundle: $0, isFrameWork: true)) }

        return allService
    }
    
    func createServiceFromStaticFrameworks()->[ApplicationService]{
        var service = [ApplicationService]()
        let allBundle = Bundle.main.paths(forResourcesOfType: "bundle", inDirectory: nil)
        allBundle.forEach { (path) in
            if let bundle = Bundle(path: path){
                service.appendList(createServiceFrom(bundle: bundle, ignoreLoad: true))
            }
        }
        return service
    }
    
    func createServiceFrom(bundle:Bundle, isFrameWork:Bool = false, ignoreLoad:Bool = false)->[ApplicationService]{
        var service = [ApplicationService]()
        
        if(ignoreLoad == false){ guard bundle.isLoaded else { return service } }
        
        guard let mainBundleName = bundle.infoDictionary?[kCFBundleNameKey as String] as? String else { return service}
        
        var realBundle = bundle
        
        if(isFrameWork){
            guard let bundlePath = bundle.path(forResource: mainBundleName, ofType: "bundle") else { return service}
            guard let frameworkBundle = Bundle(path: bundlePath) else { return service}
            realBundle = frameworkBundle
        }
        
        guard let path = realBundle.path(forResource: "Config", ofType: "plist") else { return service}
        let mainConfig = NSDictionary(contentsOfFile: path)
        service.appendList(createService(config: mainConfig, bundleName: mainBundleName))
        return service
    }
    
    func createService(config:NSDictionary?, bundleName:String)->[ApplicationService]{
        
        var service = [ApplicationService]()
        guard let serviceList = config?["AppDelegateService"] as? Array<String> else { return service}
        
        serviceList.forEach { name in
            let serviceClass = NSClassFromString("\(bundleName).\(name)")
            if let ser = serviceClass as? ApplicationService.Type{
                service.append((ser as! NSObject.Type).init() as! ApplicationService)
            }
        }
        return service
    }
}


